package com.quiz.common.mybatis.handler;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.http.HttpStatus;
import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import com.quiz.common.core.domain.model.LoginUser;
import com.quiz.common.exception.ServiceException;
import com.quiz.common.utils.SecurityUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.reflection.MetaObject;
import org.springframework.security.core.context.SecurityContextHolder;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * @className: CreateAndUpdateMetaObjectHandler
 * @description: MP注入处理器
 * @author: ahuan
 * @createDate: 2023-08-03 11:03:02
 * @updateUser:
 * @updateDate:
 * @updateRemark:
 * @version: 1.0.0
 */
@Slf4j
public class CreateAndUpdateMetaObjectHandler implements MetaObjectHandler {

    /**
     * 排除自动填充的实体
     */
    protected static final List<String> EXCLUDE_CLASSES = new ArrayList<>();

    private static final String ERROR_MSG = "自动注入异常 => ";


    static {

    }


    @Override
    public void insertFill(MetaObject metaObject) {
        boolean exclude = isExclude(metaObject);
        if (exclude) {
            return;
        }
        try {
            if (ObjectUtil.isNotNull(metaObject)) {
                strictInsertFill(metaObject, "createTime", Date.class, new Date());
                strictInsertFill(metaObject, "updateTime", Date.class, new Date());
                strictInsertFill(metaObject, "createBy", String.class, getLoginUserIdStr());
                strictInsertFill(metaObject, "createName", String.class, getLoginUserNickName());
                strictInsertFill(metaObject, "updateBy", String.class, getLoginUserIdStr());
                strictInsertFill(metaObject, "deptId", Long.class, getLoginUser().getDeptId());
            }
        } catch (Exception e) {
            log.error(ERROR_MSG + e.getMessage(),e);
            throw new ServiceException(ERROR_MSG + e.getMessage(), HttpStatus.HTTP_INTERNAL_ERROR);
        }
    }

    @Override
    public void updateFill(MetaObject metaObject) {
        boolean exclude = isExclude(metaObject);
        if (exclude) {
            return;
        }
        try {
            if (ObjectUtil.isNotNull(metaObject)) {
                strictUpdateFill(metaObject, "updateTime", Date.class, new Date());
                strictUpdateFill(metaObject, "updateBy", String.class, getLoginUserIdStr());
            }
        } catch (Exception e) {
            log.error(ERROR_MSG + e.getMessage(),e);
            throw new ServiceException(ERROR_MSG + e.getMessage(), HttpStatus.HTTP_INTERNAL_ERROR);
        }
    }

    /**
     * 获取登录用户id
     *
     * @return {@link String }
     * @author ahuan
     * @date 2023-08-03 11:02:32
     **/
    private LoginUser getLoginUser() {
        try {
            //TODO 获取用户信息
//            return (LoginUser) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
            return SecurityUtils.getLoginUser();
        } catch (Exception e) {
            //处理不携带token的情况
            return null;
        }
    }

    /**
     * 获取登录用户id
     *
     * @return {@link String }
     * @author ahuan
     * @date 2023-08-03 11:02:32
     **/
    private Long getLoginUserId() {
        try {
            //TODO 获取用户信息
            LoginUser principal = (LoginUser) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
            return principal.getUserId();
        } catch (Exception e) {
            //处理不携带token的情况
            return null;
        }
    }

    /**
     * 获取登录用户id
     *
     * @return {@link String }
     * @author ahuan
     * @date 2023-08-03 11:02:32
     **/
    private String getLoginUserIdStr() {
        try {
            //TODO 获取用户信息
            return getLoginUser().getUserId().toString();
        } catch (Exception e) {
            //处理不携带token的情况
            return null;
        }
    }
    private String getLoginUserNickName() {
        try {
            return getLoginUser().getUser().getNickName();
        } catch (Exception e) {
            //处理不携带token的情况
            return null;
        }
    }

    /**
     * 判断是否属于排除对象
     *
     * @param metaObject 元对象
     * @return boolean
     * @author ahuan
     * @date 2022-01-10 15:27:35
     **/
    public boolean isExclude(MetaObject metaObject) {
        if (CollUtil.isNotEmpty(EXCLUDE_CLASSES)) {
            Object originalObject = metaObject.getOriginalObject();
            for (String cls : EXCLUDE_CLASSES) {
                try {
                    Class<?> clazz = Class.forName(cls);
                    if (originalObject.getClass().isInstance(clazz.newInstance())) {
                        return true;
                    }
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException e) {
                    log.error("{} {}", ERROR_MSG, e.getMessage());
                    throw new ServiceException(ERROR_MSG + e.getMessage(), HttpStatus.HTTP_INTERNAL_ERROR);
                }
            }
        }
        return false;
    }
}
